var gulp 	= require('gulp');
var gutil 	= require('gulp-util');
var bower 	= require('bower');
var concat 	= require('gulp-concat');
var sass 	= require('gulp-sass');
var rename 	= require('gulp-rename');
var sh 		= require('shelljs');
var connect = require('gulp-connect');

var imagemin= require('gulp-imagemin');
var changed = require('gulp-changed');
var jshint 	= require('gulp-jshint');
var uglify 	= require('gulp-uglify');
var coffee 	= require('gulp-coffee');
var plumber = require('gulp-plumber');
var minifyCss 	 = require('gulp-minify-css');
var handleErrors = require('./util/handleErrors2');
var bundleLogger = require('./util/bundleLogger');
var browserify   = require('browserify');
var source       = require('vinyl-source-stream');


var requireDir = require('require-dir');
// Require all tasks in gulp/tasks, including subfolders
requireDir('./tasks', { recurse: true });


var config = {
	sass: {
		watch: ['./src/scss/*.scss'],
		src: ['./src/scss/app.scss', './src/scss/style.scss'],    
		dest: "./www/css"
	},
	htmlpage: {
		watch: ['./src/**/*.html'],
		src: ['./src/**/*.html',
			"!./src/exclude.html"
		],
		dest: './www'
	},
	images: {
		src: "./src/images/**",
		dest: './www/images'
	},
	basejs: {
		src: [
			"./src/basejs/jquery-1.10.2.min.js",
			"./src/basejs/angular/angular.min.js", 
			'./src/basejs/angular/*.min.js', 
			'./src/basejs/angular-ui/*.min.js'
			//排除文件
			//"!" + src + "/scripts/angular/angular-animate.min.js"
		],
		dest: './www/scripts',
		outputName: 'base.min.js'
	},
	scripts: {
		watch: './src/scripts/**/*.js',
		bundleConfigs: [
			{
				src: ['./src/scripts/home.*.js'],
				dest: './www/scripts',
				outputName: 'home.others.js'			
			}
		]
	},
	seajs: {
		src: ['./src/seajs/**/*.js'],
		dest: './www/seajs'
	},
	coffee: {
		src: './src/coffee/*.{coffee, hbs}',
		dest: './www/scripts',
		outputName: 'coffee.js'
	},
	browserify: {
		watch: './src/browserify/*.js',
		bundleConfigs: [
			{
				src: './src/browserify/home.app.js',
				dest: './www/scripts',
				outputName: 'browserify.home.js',
				isRequire: false
			},			
			{
				src: './src/browserify/require.home.app.js',
				dest: './www/scripts',
				outputName: 'browserify.require.home.js',
				isRequire: true,
				outputModuleName: 'home'
			}
		]
	}
}

gulp.task('default', ['watch', 'connect', 'connectDev']);
gulp.task('bundle', ['htmlpage', 'sass', 'images','scripts', 'scripts.basejs', 'coffee', 'seajs', 'browserify'])

gulp.task('htmlpage', function() { 
  gulp.src(config.htmlpage.src)
    .pipe(changed(config.htmlpage.dest))
    //.pipe(minifyHTML())
    .pipe(gulp.dest(config.htmlpage.dest));
});

gulp.task('sass', function(done) {
	gulp.src(config.sass.src)
		.pipe(plumber({errorHandler: handleErrors}))
		.pipe(sass())
		.pipe(gulp.dest(config.sass.dest))
		.pipe(minifyCss({
			keepSpecialComments: 0
		}))
		.pipe(rename({ extname: '.min.css' }))
		.pipe(gulp.dest(config.sass.dest))
		.on('end', done);
});

//lint任务将检查我们js/目录下的所有JavaScript文件并确保我们的代码没有错误。
gulp.task('jshint',function(){
    gulp.src(config.scripts.watch)
    .pipe(changed(config.scripts.watch)) // Ignore unchanged files
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

gulp.task('scripts', ['jshint'], function(callback) {
	var bundleQueue = config.scripts.bundleConfigs.length;
	
	var scriptThis = function(bundleConfig) {
		// Log when bundling starts
		bundleLogger.start(bundleConfig.outputName);

		var reportFinished = function() {
			// Log when bundling completes
	      	bundleLogger.end(bundleConfig.outputName)

	      	if(bundleQueue) {
	        	bundleQueue--;
	        	if(bundleQueue === 0) {
	          		callback();
	    		}
	      	}
		};

		return gulp.src(bundleConfig.src)
	        .pipe(concat(bundleConfig.outputName))
	        .pipe(gulp.dest(bundleConfig.dest))
	        .pipe(rename({ extname: '.min.js' }))	//rename("other.min.js")
	        .pipe(uglify())
	        .pipe(gulp.dest(bundleConfig.dest))
			.on('end', reportFinished);
	}
	
	config.scripts.bundleConfigs.forEach(scriptThis);
}); 

gulp.task('scripts.basejs', function() {
    gulp.src(config.basejs.src)
        .pipe(concat(config.basejs.outputName))
        .pipe(gulp.dest(config.basejs.dest))
});  

gulp.task('seajs', function() {
    gulp.src(config.seajs.src)
        .pipe(gulp.dest(config.seajs.dest))
});

gulp.task('browserify', function(callback) {
	var bundleQueue = config.browserify.bundleConfigs.length;
	
	var browserifyThis = function(bundleConfig) {
		// Log when bundling starts
		bundleLogger.start(bundleConfig.outputName);

		var reportFinished = function() {
			// Log when bundling completes
	      	bundleLogger.end(bundleConfig.outputName)

	      	if(bundleQueue) {
	        	bundleQueue--;
	        	if(bundleQueue === 0) {
	          		callback();
	    		}
	      	}
		};

		var bundleBrowserify = browserify();
		if(bundleConfig.isRequire){
			bundleBrowserify.require(bundleConfig.src, {expose: bundleConfig.outputModuleName})	//此生成html调用时需要用require(moduleName)
		}
		else{
			bundleBrowserify.add(bundleConfig.src)
		}
		bundleBrowserify.bundle()
			.pipe(plumber({errorHandler: handleErrors}))
		    //Pass desired output filename to vinyl-source-stream
		    .pipe(source(bundleConfig.outputName))
		    // Start piping stream to tasks!
		    .pipe(gulp.dest(bundleConfig.dest));

		//直接连着uglify会报错
		return gulp.src(bundleConfig.dest + "/" + bundleConfig.outputName)
		    .pipe(rename({ extname: '.min.js' }))	//rename("other.min.js")
	        .pipe(uglify())
	        .pipe(gulp.dest(bundleConfig.dest))
			.on('end', reportFinished);
	}
	
	config.browserify.bundleConfigs.forEach(browserifyThis);
});

gulp.task('coffee', function(){
	return gulp.src(config.coffee.src)
		.pipe(plumber({errorHandler: handleErrors}))
		.pipe(coffee())
		.pipe(concat(config.coffee.outputName))
        .pipe(gulp.dest(config.coffee.dest))
		.pipe(rename({ extname: '.min.js' }))
        .pipe(uglify())
        .pipe(gulp.dest(config.coffee.dest))
		
});

gulp.task('images', function() {
  return gulp.src(config.images.src)
    .pipe(changed(config.images.dest)) // Ignore unchanged files
    .pipe(imagemin()) // Optimize  .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest(config.images.dest));
});

gulp.task('watch', ['bundle'], function() {
	gulp.watch(config.sass.watch, ['sass', 'reload']);
	gulp.watch(config.htmlpage.watch, ['htmlpage', 'reload']);
	gulp.watch(config.scripts.watch, ['scripts', 'reload']);
	gulp.watch(config.coffee.src, ['coffee', 'reload']);
	gulp.watch(config.seajs.src, ['seajs', 'reload']);
	gulp.watch(config.browserify.watch, ['browserify', 'reload']);

	//gulp.watch(config.basejs.src, function(){
	//	gulp.run('jshint', 'scripts');
	//});
});

gulp.task('connect', function() {
	connect.server({
		//root: ['www'],			//访问不了src中的exclude.html
		root: ['www', 'src'],		//可以访问src中的exclude.html
		livereload: true
	});
});

gulp.task('connectDev', function() {
	connect.server({
		port: 9006,
		root: ['src'],		
		livereload: true
	});
});

gulp.task('reload', function () {
	gulp.src(config.htmlpage.watch)
		.pipe(connect.reload());
});
 


